package com.starleague.battletech.unit.mech;

import com.starleague.battletech.BattletechException;
import com.starleague.battletech.unit.BattletechUnitEngineType;
import com.starleague.battletech.unit.IWeight;
import com.starleague.battletech.unit.ImmutableWeight;

public abstract class AbstractMechEngineFactory
{
    public final IMechEngine addEngine(IMutableMech mech,
                                       BattletechUnitEngineType engineType,
                                       int walkMovementPoints) throws BattletechException
    {
        int engineRating = calcEngineRating(mech, walkMovementPoints);
        IWeight engineWeight = calcEngineWeight(engineRating, engineType);
        return addEngine(mech, engineWeight, engineType, engineRating);
    }

    protected abstract IMechEngine addEngine(IMutableMech mech,
                                             IWeight engineWeight,
                                             BattletechUnitEngineType engineType,
                                             int engineRating) throws BattletechException;

    protected int getNumRequiredSideTorsoSlots(BattletechUnitEngineType engineType) throws BattletechException
    {
        switch (engineType)
        {
            case NORMAL:
                return 0;
            case XL_CLAN:
                return 2; // TODO: Make not hard-coded
            case XL_IS:
                return 3; // TODO: Make not hard-coded
        }
        throw new BattletechException("unknown BattletechUnitEngineType: " + engineType);
    }

    private int calcEngineRating(IMutableMech mech,
                                 int walkMovementPoints)
    {
        return mech.getWeight().getTonsAsInteger() * walkMovementPoints;
    }

    private ImmutableWeight calcEngineWeight(int engineRating,
                                             BattletechUnitEngineType engineType) throws BattletechException
    {
        int engineCentiTonsRecord[] = engineRatingCentiTonsChart[engineRating / 5];

        switch (engineType)
        {
            case NORMAL:
                return new ImmutableWeight(engineCentiTonsRecord[0] * 0.01);

            case XL_IS:
            case XL_CLAN:
                return new ImmutableWeight(engineCentiTonsRecord[1] * 0.01);
        }
        throw new BattletechException("Unknown BattletechUnitEngineType: " + engineType);
    }

    // /**
    // * rating/5 => tonnage
    // */
    // private static final float[] engineRatingTonsChart = {
    // 0.0f,
    // 0.25f,
    // 0.5f,
    // 0.5f,
    // 0.5f,
    // 0.5f,
    // 1.0f,
    // 1.0f,
    // 1.0f,
    // 1.0f,
    // 1.5f,
    // 1.5f,
    // 1.5f,
    // 2.0f,
    // 2.0f,
    // 2.0f,
    // 2.5f,
    // 2.5f,
    // 3.0f,
    // 3.0f,
    // 3.0f,
    // 3.5f,
    // 3.5f,
    // 4.0f,
    // 4.0f,
    // 4.0f,
    // 4.5f,
    // 4.5f,
    // 5.0f,
    // 5.0f,
    // 5.5f,
    // 5.5f,
    // 6.0f,
    // 6.0f,
    // 6.0f,
    // 7.0f,
    // 7.0f,
    // 7.5f,
    // 7.5f,
    // 8.0f,
    // 8.5f,
    // 8.5f,
    // 9.0f,
    // 9.5f,
    // 10.0f,
    // 10.0f,
    // 10.5f,
    // 11.0f,
    // 11.5f,
    // 12.0f,
    // 12.5f,
    // 13.0f,
    // 13.5f,
    // 14.0f,
    // 14.5f,
    // 15.5f,
    // 16.0f,
    // 16.5f,
    // 17.5f,
    // 18.0f,
    // 19.0f,
    // 19.5f,
    // 20.5f,
    // 21.5f,
    // 22.5f,
    // 23.5f,
    // 24.5f,
    // 25.5f,
    // 27.0f,
    // 28.5f,
    // 29.5f,
    // 31.5f,
    // 33.0f,
    // 34.5f,
    // 36.5f,
    // 38.5f,
    // 41.0f,
    // 43.5f,
    // 46.0f,
    // 49.0f,
    // 52.5f,
    // // <=400
    // // 56.5f,
    // // 61.0f,
    // // 66.5f,
    // // 72.5f,
    // // 79.5f,
    // // 87.5f,
    // // 97.0f,
    // // 107.5f,
    // // 119.5f,
    // // 133.5f,
    // // 150.0f,
    // // 168.5f,
    // // 190.0f,
    // // 214.5f,
    // // 243.0f,
    // // 275.5f,
    // // 313.0f,
    // // 356.0f,
    // // 405.5f,
    // // 462.5f,
    // };

    /**
     * TODO: Move this into a DB or data loader. NOT hard-coded in this class All values are 100X the actual tonnage,
     * and need to be divided by 100 before use. Thus the 'c' ('c' for 'centi' = one hundredth) prefix before 'tons'.
     * Each row represents a particular engine rating, divided by 5 (Rating 50 == row_index 10) Ratings [0 - 400]
     */
    private final static int[][] engineRatingCentiTonsChart = {
            //
            // [STD, XL, **COMPACT, **LIGHT] <== [** = TODO!]
            //
            null, // rating 0
            { 25, 25 }, // rating 5
            { 50, 50 }, // rating 10
            { 50, 50 }, // rating 15
            { 50, 50 }, // rating 20
            { 50, 50 },
            { 100, 50 }, // rating 30
            { 100, 50 },
            { 100, 50 },
            { 100, 50 },
            { 150, 100 }, // rating 50
            { 150, 100 },
            { 150, 100 },
            { 200, 100 },
            { 200, 100 },
            { 200, 100 },
            { 250, 150 }, // rating 80
            { 250, 150 },
            { 300, 150 },
            { 300, 150 },
            { 300, 150 }, // rating 100
            { 350, 200 },
            { 350, 200 },
            { 400, 200 },
            { 400, 200 },
            { 400, 200 },
            { 450, 250 },
            { 450, 250 },
            { 500, 250 },
            { 500, 250 }, // rating 145
            { 550, 300 },
            { 550, 300 },
            { 600, 300 },
            { 600, 300 },
            { 600, 300 }, // rating 170
            { 700, 350 },
            { 700, 350 },
            { 750, 400 },
            { 750, 400 },
            { 800, 400 }, // rating 195
            { 850, 450 },
            { 850, 450 },
            { 900, 450 }, // rating 210
            { 950, 500 },
            { 1000, 500 },
            { 1000, 500 },
            { 1050, 550 }, // rating 230
            { 1100, 550 },
            { 1150, 600 },
            { 1200, 600 },
            { 1250, 650 },
            { 1300, 650 },
            { 1350, 700 },
            { 1400, 700 },
            { 1450, 750 }, // rating 270
            { 1550, 800 },
            { 1600, 800 },
            { 1650, 850 },
            { 1750, 900 },
            { 1800, 900 },
            { 1900, 950 },
            { 1950, 1000 }, // rating 305
            { 2050, 1050 },
            { 2150, 1100 },
            { 2250, 1150 },
            { 2350, 1200 },
            { 2450, 1250 },
            { 2550, 1300 },
            { 2700, 1350 },
            { 2850, 1450 }, // rating 345
            { 2950, 1500 },
            { 3150, 1600 },
            { 3300, 1650 },
            { 3450, 1750 },
            { 3650, 1850 },
            { 3850, 1950 },
            { 4100, 2050 },
            { 4350, 2200 },
            { 4600, 2300 },
            { 4900, 2450 },
            { 5250, 2650 }, // rating 400
    };
}
